package generator;

import java.util.*;

public class MotifGenerator {

	public static double convergence = 0.001;
	
	public static void main(String [] args)
	{
		System.out.println("Random motif!!!!!");
		Vector<Vector<Double>> randomMotif = getRandomMotif(200, 1.5);
		
		double cumcum = 0;
		for(Vector<Double> seq : randomMotif) //probability for each idx
		{
			System.out.println(seq);
			double cum = 0.0;
			double sum = 0.0;
			for (Double d : seq)
			{
				sum += d;
				if (d > 0)
					cum += d * log_base(d, 2);
			}
			cum -= log_base(0.25, 2);
			cumcum += cum;
			System.out.println("Seq info : " + cum + " sum : " + sum);
		}
		System.out.println("cumcum: " + cumcum);
		System.out.println("Random motif : " + randomMotif);
	}
	
	public static Vector<Vector<Double>> getRandomMotif(int ml, double icpc)
	{
		double targetCum = ml * icpc;
		Vector<Vector<Double>> randomMotif = new Vector<Vector<Double>>();
		Random r = new Random();

		for (int sidx = 0; sidx < ml; sidx++)
		{
			Vector<Double> currMotif = new Vector<Double>();
			if (icpc == 2.0) 
			{
				int allInIdx = (int)(4 * Math.random());
				for (int i = 0; i < 4; i++) {
					if (allInIdx == i) currMotif.add(1.0);
					else currMotif.add(0.0);
				}
			}
			else
			{
				double val1 = r.nextGaussian() + 0.5; //renormalize to mean = 1
				double val2 = r.nextGaussian() + 0.5;
				double val3 = r.nextGaussian() + 0.5;
				val1 = (val1 >= 0) ? val1 : 0.0;
				val2 = (val2 >= 0) ? val2 : 0.0;
				val3 = (val3 >= 0.9) ? val3 : 0.9;
				
				double p1,p2,p3,p4;
				if (icpc == 1.)
				{
					p1 = 0.001 * val1;
					p2 = 0.001 * val2;
					val3 = (val3 < 1.1) ? val3 : 1.1;
					p3 = 0.499 * val3;
					p4 = 1.0 - p1 - p2 - p3;
				}
				else if (icpc == 1.5)
				{
					p1 = 0.0005 * val1;
					p2 = 0.0005 * val2;
					val3 = (val3 > 0.95) ? val3 : 0.95;
					val3 = (val3 < 1.05) ? val3 : 1.05;
					p3 = 0.888 * val3;
					p4 = 1.0 - p1 - p2 - p3;
				}
				else {
					p1 = 0;
					p2 = 0;
					p3 = 0; 
					p4 = 0;
				} // unsupported
				currMotif.add(p1);
				currMotif.add(p2);
				currMotif.add(p3);
				currMotif.add(p4);
			}
			Collections.shuffle(currMotif);
			randomMotif.add(currMotif);
		}
		return randomMotif;
	}
	
	public static double log_base(double a, double base)
	{
		return Math.log(a) / Math.log(base);
	}
}
